#ifndef __IM_MACROS_H__
#define __IM_MACROS_H__

/**
 * @defgroup IMMacros Macros
 * @ingroup PublicIME
 * @{
 */

/* Guard C code in headers, while including them from C++ */
#ifdef __cplusplus
#  define IM_BEGIN_DECLS  extern "C" {
#  define IM_END_DECLS    }
#else
#  define IM_BEGIN_DECLS
#  define IM_END_DECLS
#endif

/* Provide definitions for some commonly used macros.
 *  Some of them are only provided if they haven't already
 *  been defined. It is assumed that if they are already
 *  defined then the current definition is correct.
 */
#ifndef NULL
#  ifdef __cplusplus
#    define NULL        (0L)
#  else /* !__cplusplus */
#    define NULL        ((void*) 0)
#  endif /* !__cplusplus */
#endif

#ifndef FALSE
#define FALSE (0)
#endif

#ifndef TRUE
#define TRUE (!FALSE)
#endif

#define IM_MAX(a, b)  (((a) > (b)) ? (a) : (b))

#define IM_MIN(a, b)  (((a) < (b)) ? (a) : (b))

#define IM_ABS(a)     (((a) < 0) ? -(a) : (a))

#define IM_CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))

/* Count the number of elements in an array. The array must be defined
 * as such; using this with a dynamically allocated array will give
 * incorrect results.
 */
#define IM_N_ELEMENTS(arr)  (sizeof (arr) / sizeof ((arr)[0]))

/* Swap two variables of given type. */
#define IM_SWAP(type,a,b)   \
    do {                    \
        type tmp = (a);     \
        (a) = (b);          \
        (b) = tmp;          \
    } while(0)

#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define IM_GNUC_WARN_UNUSED_RESULT                        \
    __attribute__((warn_unused_result))
#else
#define IM_GNUC_WARN_UNUSED_RESULT
#endif /* __GNUC__ */

/* Here we provide IM_GNUC_EXTENSION as an alias for __extension__,
 * where this is valid. This allows for warningless compilation of
 * "long long" types even in the presence of '-ansi -pedantic'.
 */
#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
#  define IM_GNUC_EXTENSION __extension__
#else
#  define IM_GNUC_EXTENSION
#endif

/** @def IM_GNUC_PRINTF
 * used to tell gcc about printf format strings
 */
/** @def IM_GNUC_NORETURN
 * used to tell gcc about functions that never return, such as abort()
 */

#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define IM_GNUC_PRINTF( format_idx, arg_idx )             \
    __attribute__((__format__ (__printf__, format_idx, arg_idx)))
#define IM_GNUC_NORETURN                                  \
    __attribute__((__noreturn__))
#else   /* !__GNUC__ */
#define IM_GNUC_PRINTF( format_idx, arg_idx )
#define IM_GNUC_NORETURN
#endif  /* !__GNUC__ */


#endif
/** @} */
/*
vi:ts=4:nowrap:ai:expandtab
*/
